#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NAME_LEN	9

//学生信息
struct stu_info {
	char 	name[NAME_LEN + 1]; /*学生姓名*/
	int		age; /*年龄*/
};

//学生节点
struct list_node {
	struct stu_info		data;
	struct list_node* 	next;
};

//节点列表（若列表非空，头指针指着第一个非空节点，尾指针指着最后一个非空节点）
struct mylist {
	struct list_node*	head;
	struct list_node*	tail;
};

//随机生成学生信息（姓名和年龄）
void rand_stu_info(struct stu_info* info) {
	for (int i = 0; i < NAME_LEN; i++) {
		info->name[i] = 'a' + (rand() % 26);
	}
	info->name[NAME_LEN] = '\0';

	info->age = rand() % 120;
}

//初始化节点列表
struct mylist* mylist_create(void) {
	struct mylist* ls = (struct mylist*)malloc(sizeof(struct mylist));
	if (ls) {
		ls->head = ls->tail = NULL;
	}

	// printf("初始化学生列表成功\n");
	return ls;
}

//删除学生节点列表
void mylist_destroy(struct mylist* ls) {
	if (!ls) {
		return;
	}
	//遍历列表，释放节点
	for (struct list_node* p = ls->head, *q; p; p = q) {
		q = p->next;
		free(p);
	}
	free(ls);
	// printf("释放学生列表成功\n");
}

//向列表插入学生信息
int mylist_insert(struct mylist* ls) {
	if (!ls) {
		return 0;
	}

	struct list_node* node = (struct list_node*)malloc(sizeof(struct list_node));
	if (!node) {
		return -1;
	}

	//生成一个学生信息
	rand_stu_info(&node->data);
	node->next = NULL;

	//插入到列表中
	if (!ls->head) {
		ls->head = node;
	}
	else {
		ls->tail->next = node;
	}
	ls->tail = node;

	// printf("插入学生：%s成功\n",ls->tail->data.name);
	return 0;
}

//遍历，打印列表
void mylist_print(struct mylist* ls) {
	if (!ls) {
		return;
	}

	for (struct list_node* p = ls->head; p; p = p->next) {
		printf("[%s, %d]->", p->data.name, p->data.age);
	}
	printf("NULL\n");
	// printf("打印学生列表成功\n");
}

int main(int argc, char* argv[]) {
	//利用系统时间来初始化系统随机数的种子值，使得每次运行由于时间不同产生而产生不同的随机数序列
	srand(time(NULL));

	struct mylist* ls = NULL;
	int ret, cmd;

	printf("1: create list\n"
		   "2: print list\n"
		   "3: insert node\n"
		   "4: quit\n");

	while (1) {
		printf(">>> ");
		scanf("%d", &cmd);

		switch (cmd) {
			case 1:
				if (ls) {
					mylist_destroy(ls);
				}

				ls = mylist_create();
				if (!ls) {
					printf("mylist_create failed\n");
					exit(-1);
				}

				break;

			case 2:
				mylist_print(ls);
				break;

			case 3:
				ret = mylist_insert(ls);
				if (ret == -1) {
					mylist_destroy(ls);
					printf("mylist_insert failed\n");
					exit(-1);
				}

				break;

			case 4:
				mylist_destroy(ls);
				exit(0);

			default:
				printf("command %d not supported\n", cmd);
				break;
			}
	}

	return 0;
}